package com.meviewer.service;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.webkit.WebResourceResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.meviewer.common.FileUtil;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ProcessingPakService {
    private HashMap<String, SQLiteDatabase> _databases = new HashMap<String, SQLiteDatabase>();
    private SQLiteDatabase getDatabase(String uri){
        if(!_databases.containsKey(uri)) {
            _databases.put(uri, SQLiteDatabase.openDatabase(uri, null, SQLiteDatabase.OPEN_READONLY));
        }

        return _databases.get(uri);
    }
    public String queryExtent(String[] uris){
        double minx = 180.0;
        double miny = 90.0;
        double maxx = -180.0;
        double maxy = -90.0;
        for(int i = 0; i < uris.length; ++i)
        {
            SQLiteDatabase database = getDatabase(uris[i]);
            String sql = "select * from " + "infos";
            Cursor cursor = database.rawQuery(sql, null);
            //利用游标遍历所有数据对象
            while (cursor.moveToNext()) {
                minx = Math.min(cursor.getDouble(0), minx);
                miny = Math.min(cursor.getDouble(1), miny);
                maxx = Math.max(cursor.getDouble(2), maxx);
                maxy  = Math.max(cursor.getDouble(3), maxy);
            }
            cursor.close();
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("minx",minx);
        jsonObject.put("miny",miny);
        jsonObject.put("maxx",maxx);
        jsonObject.put("maxy",maxy);
        return jsonObject.toJSONString();
    }

    public void closeDatabase(String uri)
    {
        SQLiteDatabase database = _databases.remove(uri);
        database.close();
    }
    //处理影像PAK文件
    public WebResourceResponse processingPak_ImageTiles(String uri, String x, String y, String z) {
        String[] uris = new String[1];
        uris[0] = uri;
        return fetchImageFromList(uris, x, y, z);
    }

    //处理影像PAK LIST文件
    public WebResourceResponse fetchImageFromList(String[] uris, String x, String y, String z) {
        return new WebResourceResponse("image/png", "utf-8",processingPakList(uris, x, y, z));
    }
    //处理DEM PAK LIST文件
    public WebResourceResponse fetchDEMFromList(String[] uris, String x, String y, String z) {
        return new WebResourceResponse("application/vnd.quantized-mesh", "ASCII",processingPakList(uris, x, y, z));
    }

    public InputStream processingPakList(String[] uris, String x, String y, String z) {
        InputStream stream = null;
        try {
            for(int i = uris.length - 1; i >= 0; --i)
            {
                SQLiteDatabase db5 = getDatabase(uris[i]);

                String imagePAKTableName = getPAKTableName(x, y, z);
                String sql = "select * from " + imagePAKTableName + " where x=? and  y=? and  z=?";

                Cursor cursor = db5.rawQuery(sql, new String[]{x, y, z});
                //利用游标遍历所有数据对象
                byte[] name = null;
                if (cursor.moveToNext()) {
                    name = cursor.getBlob(cursor.getColumnIndex("tile"));
                }
                if (name != null) {
                    stream = new ByteArrayInputStream(name);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stream;
    }

    public String getPAKTableName(String x,String y,String z){

        Integer x1 = Integer.parseInt(x);
        Integer y1 = Integer.parseInt(y);
        Integer z1 = Integer.parseInt(z);
        if(z1 < 10){
            return "blocks";
        }else {
            String x2 = String.valueOf(x1 / 512);
            String y2 = String.valueOf(y1 / 512);
            return "blocks_" + z1 +"_"+x2 + "_" + y2;
        }

    }
    
    public WebResourceResponse fetchLayerJsonFromList(String[] pakPathList)
    {
        List<List<Map<String,Object>>> list_available = new ArrayList();

        double minX = Double.POSITIVE_INFINITY;
        double minY = Double.POSITIVE_INFINITY;
        double maxX = Double.NEGATIVE_INFINITY;
        double maxY = Double.NEGATIVE_INFINITY;

        String projectionStr = null;
        for (String file : pakPathList) {
            SQLiteDatabase db5 = getDatabase(String.valueOf(file));

            // 读取info表获取相关信息
            Cursor cursor = db5.rawQuery("select layerjson from infos", null);

            if(!cursor.moveToNext())
            {
                continue;
            }

            String layerJson = new String(cursor.getBlob(0));

            JSONObject rootObject = JSON.parseObject(layerJson);
            JSONArray boundsArray = rootObject.getJSONArray("bounds");
            minX = Double.min(boundsArray.getDouble(0), minX);
            minY = Double.min(boundsArray.getDouble(1), minY);
            maxX = Double.max(boundsArray.getDouble(2), maxX);
            maxY = Double.max(boundsArray.getDouble(3), maxY);

            if(null == projectionStr)
            {
                projectionStr = rootObject.getString("projection");
            }

            Cursor cursor1 = db5.rawQuery("select * from sqlite_master where type ='table'", null);
            List<String> list_table = new ArrayList<>();
            while(cursor1.moveToNext()){
                String tableName = cursor1.getString(cursor1.getColumnIndex("name"));

                //取表名中含有blocks但不是blocks的表名
                if(tableName.contains("blocks") && !tableName.equals("blocks")){
                    list_table.add(cursor1.getString(cursor1.getColumnIndex("name")));
                }
            }
            //先处理0-9级的每级x、y范围
            Cursor cursor2 = db5.rawQuery("select min(x) as minx ,max(x) as maxx,min(y) as miny ,max(y) as maxy from blocks group by z", null);
            List<Map<String,Object>> list_0toMax_z = new ArrayList();
            int count = 0;
            String minx = "";
            String maxx = "";
            String miny = "";
            String maxy = "";
            while(cursor2.moveToNext()){
                minx = cursor2.getString(cursor2.getColumnIndex("minx"));
                maxx = cursor2.getString(cursor2.getColumnIndex("maxx"));
                miny = cursor2.getString(cursor2.getColumnIndex("miny"));
                maxy = cursor2.getString(cursor2.getColumnIndex("maxy"));
                Map<String,Object> map = new HashMap<>();
                map.put("minx",minx);
                map.put("maxx",maxx);
                map.put("miny",miny);
                map.put("maxy",maxy);
                map.put("index",count);
                list_0toMax_z.add(map);
                count = count +1 ;
            }

            if(list_table.size() != 0){
                for (String s : list_table) {

                    String[] s_arr = s.split("_");
                    //拿到z大于9的表名中的z的值
                    Integer a =Integer.parseInt(s_arr[1]);

                    Cursor cursor_dayu9 = db5.rawQuery("select min(x) as minx ,max(x) as maxx,min(y) as miny ,max(y) as maxy from "+s+" group by z", null);
                    while(cursor_dayu9.moveToNext()){

                        minx = cursor_dayu9.getString(cursor_dayu9.getColumnIndex("minx"));
                        maxx = cursor_dayu9.getString(cursor_dayu9.getColumnIndex("maxx"));
                        miny = cursor_dayu9.getString(cursor_dayu9.getColumnIndex("miny"));
                        maxy = cursor_dayu9.getString(cursor_dayu9.getColumnIndex("maxy"));
                        Map<String,Object> map = new HashMap<>();
                        map.put("minx",minx);
                        map.put("maxx",maxx);
                        map.put("miny",miny);
                        map.put("maxy",maxy);
                        map.put("index",a);

                        list_0toMax_z.add(map);
                    }
                }
            }
            list_available.add(list_0toMax_z);
        }
        List<Integer> list_count = new ArrayList();
        for (int i = 0; i < list_available.size(); i++) {
            list_count.add(list_available.get(i).size());
        }



        List list_result = new ArrayList();
        //获得几个层级最高的长度
        int max = Collections.max(list_count);

        for (int i = 0; i < max; i++) {
            list_result.add(new ArrayList<JSONObject>());
        }

        for (List<Map<String, Object>> list_ava : list_available) {
            for (Map<String, Object> map : list_ava) {

                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("startX",Integer.parseInt(map.get("minx").toString()));
                jsonObject1.put("startY",Integer.parseInt(map.get("miny").toString()));
                jsonObject1.put("endX",Integer.parseInt(map.get("maxx").toString()));
                jsonObject1.put("endY",Integer.parseInt(map.get("maxy").toString()));
                List list = (List) list_result.get(Integer.parseInt(map.get("index").toString()));
                list.add(jsonObject1);
            }
        }

        JSONObject rootObject = new JSONObject();
        rootObject.put("available",list_result);
        rootObject.put("minzoom", 0);
        rootObject.put("maxzoom", max);
        rootObject.put("scheme", "tms");
        rootObject.put("projection", projectionStr);
        rootObject.put("format", "quantized-mesh-1.0");
        rootObject.put("name", "MEV");
        rootObject.put("version", "1.0.0");
        rootObject.put("tilejson", "1.0");

        JSONArray boundsArray = new JSONArray();
        boundsArray.add(minX);
        boundsArray.add(minY);
        boundsArray.add(maxX);
        boundsArray.add(maxY);

        rootObject.put("bounds", boundsArray);

        JSONArray tileURLFormatArray = new JSONArray();
        tileURLFormatArray.add("{z}/{x}/{y}.terrain");
        rootObject.put("tiles", tileURLFormatArray);

        String jsonString = rootObject.toJSONString();
        return new WebResourceResponse("application/json", "utf-8",new ByteArrayInputStream(jsonString.getBytes()));
    }
}
